package cn.like.satoken.token;

import cn.dev33.satoken.dao.SaTokenDaoRedisJackson;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.like.common.context.redisKey.AuthRedisKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * desc: 令牌侦听器 <br>
 * details: token 监听，比如说登录，注销等等情况
 *
 * @author like 980650920@qq.com
 * @date 2021-07-11 12:52:04
 * @see SaTokenListener
 */
@Component
@Slf4j
public class TokenListener implements SaTokenListener {

    public final SaTokenDaoRedisJackson saTokenDaoRedisJackson;

    public TokenListener(SaTokenDaoRedisJackson saTokenDaoRedisJackson) {this.saTokenDaoRedisJackson = saTokenDaoRedisJackson;}


    /**
     * 每次登录时触发
     */
    @Override
    public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {
        log.info("[ login ] 当前有用户登录：id:[ {} ]", loginId);
    }

    /**
     * 每次注销时触发
     */
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        log.info("[ logout ] 当前有用户注销：id:[ {} ]", loginId);
        // 删除token
        deleteToken(TokenHelper.tokenKey(tokenValue));
        // 删除权限
        deletePermissionsAndRole(loginId);
    }

    /**
     * 每次被踢下线时触发
     */
    @Override
    public void doLogoutByLoginId(String loginType, Object loginId, String tokenValue, String device) {
        log.info("[ logout ] 当前有用户被踢下线：id:[ {} ]", loginId);
        // 删除token
        deleteToken(TokenHelper.tokenKey(tokenValue));
        // 删除权限
        deletePermissionsAndRole(loginId);
    }

    /**
     * 每次被顶下线时触发
     */
    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue, String device) {
        log.info("[ logout ] 当前有用户被顶下线：id:[ {} ]", loginId);
        // 删除token
        deleteToken(TokenHelper.tokenKey(tokenValue));
        // 删除权限
        deletePermissionsAndRole(loginId);

        // todo 通知用户
    }

    /**
     * 每次被封禁时触发
     */
    @Override
    public void doDisable(String loginType, Object loginId, long disableTime) {
        log.info("[ logout ] 当前有用户被封禁：id:[ {} ]", loginId);
        // ... 
    }

    /**
     * 每次被解封时触发
     */
    @Override
    public void doUntieDisable(String loginType, Object loginId) {
        log.info("[ logout ] 当前有用户被踢下线：id:[ {} ]", loginId);
        // ... 
    }

    /**
     * 每次创建Session时触发
     */
    @Override
    public void doCreateSession(String id) {
        // ... 
    }

    /**
     * 每次注销Session时触发
     */
    @Override
    public void doLogoutSession(String id) {
        // ... 
    }

    // =====================  private
    private void deletePermissionsAndRole(Object loginId) {
        saTokenDaoRedisJackson.stringRedisTemplate.opsForHash().delete(AuthRedisKey.permissions_cache_key.keyStyle(), loginId);
        saTokenDaoRedisJackson.stringRedisTemplate.opsForHash().delete(AuthRedisKey.role_cache_key.keyStyle(), loginId);
    }

    private void deleteToken(String tokenValue) {
        saTokenDaoRedisJackson.delete(tokenValue);
    }

}